package com.levi.test.service;

import com.alibaba.fastjson.JSONObject;
import com.levi.test.bean.ExecuteRequest;
import com.levi.test.util.ExecuteHttpUtil;
import com.levi.test.util.SpringContextExecuteUtil;

import java.lang.reflect.Method;

public class ExecuteService {

    public static String executeByProxy(ExecuteRequest req) throws Exception {
        //将字符串转为对象
        if (req.getO().length > 0) {
            for (int i = 0; i < req.getO().length; i++) {
                String oStr = JSONObject.toJSONString(req.getO()[i]);
                if (oStr != null &&
                        ((oStr.startsWith("{") && oStr.endsWith("}"))
                                || (oStr.startsWith("[") && oStr.endsWith("]")))) {
                    req.getO()[i] = JSONObject.parseObject(oStr, req.getT()[i]);
                }
            }
        }
        Object bean = null;
        try {
            bean = SpringContextExecuteUtil.getBean(req.getC());
        } catch (Exception e) {
            bean = req.getC().newInstance();
        }
        Method method = (req.getT() != null && req.getT().length > 0) ?
                req.getC().getDeclaredMethod(req.getM(), req.getT()) : req.getC().getDeclaredMethod(req.getM());
        method.setAccessible(true);
        long beginTime = System.currentTimeMillis();
        Object invoke = (req.getO() != null && req.getO().length > 0) ? method.invoke(bean, req.getO()) : method.invoke(bean);
        String time = " 耗时：" + (System.currentTimeMillis() - beginTime) + " ms";
        String resp = JSONObject.toJSONString(invoke) + time;
        System.out.println("响应：" + resp);
        return resp;
    }

    public static String execute(ExecuteRequest req) {
        if (req.getT().length > 0 || req.getO().length == 0) {
            String resp = ExecuteHttpUtil.http(JSONObject.toJSONString(req));
            return resp;
        }
        Class[] t = new Class[req.getO().length];
        for (int i = 0; i < req.getO().length; i++) {
            Object o = req.getO()[i];
            if (o == null) {
                throw new RuntimeException("执行方法的参数列表不能为空");
            }
            t[i] = o.getClass();
        }
        req.setT(t);
        Method me = null;
        Method[] methods = req.getC().getDeclaredMethods();
        for (Method m : methods) {
            if (!m.getName().equals(req.getM())) {
                continue;
            }
            Class<?>[] types = m.getParameterTypes();
            if (types.length == 0) {
                continue;
            }
            if (types.length != t.length) {
                continue;
            }
            boolean flag = true;
            for (int i = 0; i < types.length; i++) {
                if (getWrapClass(types[i]) != getWrapClass(t[i])) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                me = m;
                break;
            }
        }
        req.setT(me.getParameterTypes());
        String resp = ExecuteHttpUtil.http(JSONObject.toJSONString(req));
        return resp;
    }

    private static Class getWrapClass(Class clz) {
        try {
            return (Class) clz.getField("TYPE").get(null);
        } catch (Exception e) {
            return clz;
        }
    }
}
